// bounce_adam implementation
// Copyright 2006 (C) Ralph Thomas

#include <view/bounce_adam.h>
#include <binder.hpp>
#include <boost/bind.hpp>

namespace view {
	struct connection_t {
		adobe::binder_helper_t	helper_m;
		adobe::name_t			name_m;
		adobe::sheet_t&			sheet_m;
		adobe::any_regular_t			last_m;
		adobe::any_regular_t			pump_m;
		adobe::any_view_t*	view_m;
		typedef adobe::any_regular_t model_type;

		void initialize()
		{
			view_m = new adobe::any_view_t(boost::ref(*this));
			sheet_m.attach_view(name_m, boost::ref(*view_m));
			helper_m.initialize(pump_m, boost::bind(&connection_t::display, this, _1), 0);
		}

		void display(const adobe::any_regular_t& val)
		{
			if( last_m == val ) return;
			last_m = val;
			sheet_m.set(name_m, val);
			sheet_m.update();
		}

		void monitor(const adobe::any_regular_t& val)
		{
			if( last_m == val ) return;
			last_m = val;
			helper_m.set(val);
		}
		void enable(bool) {}

		connection_t( const adobe::any_regular_t& pump, const adobe::name_t& name, adobe::sheet_t& sheet, const adobe::factory_token_t& token)
		 : helper_m(sheet), name_m(name), sheet_m(sheet), pump_m(pump), view_m(0)
		{
			boost::function<void()> fn(boost::bind(&connection_t::initialize, this));
			token.client_holder_m.show_window_m.connect(fn);
		}

		~connection_t()
		{
			if (view_m) {
				sheet_m.detach_view(name_m, boost::ref(*view_m));
				delete view_m;
			}
		}
	};
	adobe::widget_node_t bounce_adam_factory(
		const adobe::dictionary_t&		parameters,
		const adobe::widget_node_t&		parent,
		const adobe::factory_token_t&	token)
	{
		adobe::dictionary_t::const_iterator i(parameters.begin());
		while (i != parameters.end()) {
			connection_t* c = new connection_t(i->second, i->first, token.sheet_m, token);
			token.client_holder_m.assemblage_m.delete_on_destruction( c );
			i++;
		}
		return parent;
	}
}
